package com.cmcc.sdtp.client;

import java.util.ArrayList;
import java.util.List;

import com.cmcc.xdr.util.TBCDUtil;

/**
 * @className：链接释放
 * @author B
 * @date:
 * @version : 1.0
 */
public class Common {
	/**
	 * @comment 公共信息头
	 * @return
	 * @version: 1.0
	 * @param length
	 */
	public static byte[] commonMessage(int length) {
		List<byte[]> list = new ArrayList<byte[]>();
		// 2字节 全F
		// 指示整个XDR所占用字节数
		int Length = length + 54;
		list.add(Util.buildNumericWithSpace(Length + "", 2));
		// 2字节 城市区号，如010代表北京 采用TBCD编码，每4个比特表示一个十进制数字
		byte[] City = TBCDUtil.parseTBCD("010");
		list.add(City);
		// 接口 一个字节
		// 1. Uu
		// 2. X2
		// 3. UE_MR
		// 4. Cell_MR
		// 5. S1-MME
		// 6. S6a
		// 7. S11
		// 8. S10
		// 9. SGs
		// 10. S5/S8
		// 11. S1-U
		// 12. Gn-C
		// 13. Gm
		// 14. Mw
		// 15. Mg
		// 16. ISC
		// 17. Sv
		// 18. Cx
		// 19. Dx
		// 20. Sh
		// 21. Dh
		// 22. Gx
		// 23. Rx
		int Interface = 17;
		list.add(Util.buildNumericWithSpace(Interface + "", 1));
		// 16个字节采集解析服务器内唯一的XDR编号，16进制编码。一个信令流程或业务传输过程生成一个XDR
		// ID。对于信令面XDR，一个XDR ID可能对应同一信令流程中的多条原始消息记录。对于MR
		// XDR，一个XDR ID对应一个MR上报。
		int XDRID = 0;
		list.add(Util.buildNumericWithSpace(XDRID + "", 16));
		// 一个字节RAT类型：
		// 1. UTRAN
		// 2. GERAN
		// 3. WLAN
		// 4. GAN
		// 5. HSPA Evolution
		// 6. EUTRAN
		int RAT = 1;
		list.add(Util.buildNumericWithSpace(RAT + "", 1));
		// 八个字节
		// 用户IMSI（TBCD编码），通过采集核心网信令获取；针对软采接口，该字段填全F，待数据合成服务器进行回填；对于Cell_MR
		// XDR，该字段为全F。
		byte[] IMSI = Util.buildStringWithSpace("FFFFFFFF", 8);
		list.add(IMSI);
		// 八个字节
		// 终端IMEI（TBCD编码），通过采集核心网信令获取；针对软采接口，该字段填全F，待数据合成服务器进行回填；
		byte[] IMEI = Util.buildStringWithSpace("FFFFFFFF", 8);
		list.add(IMEI);
		return Util.bulidByteArr(list);
	}

	/**
	 * @comment 公共信息头2 这个是合成服务器的那个
	 * @return
	 * @version: 1.0
	 * @param length
	 */
	public static byte[] commonMessage2(int length) {
		List<byte[]> list = new ArrayList<byte[]>();
		// Length unsigned int 2 全F 指示整个XDR所占用字节数
		int Length = length + 54;
		list.add(Util.buildNumericWithSpace(Length + "", 2));
		// City byte 2 全F 城市区号，如010代表北京
		// 采用TBCD编码，每4个比特表示一个十进制数字
		byte[] City = TBCDUtil.parseTBCD("010");
		list.add(City);
		// RAT unsigned int 1 全F 1：UTRAN
		// 2：GERAN
		// 3：WLAN
		// 4：GAN
		// 5：HSPA Evolution
		// 6：EUTRAN
		int RAT = 1;
		list.add(Util.buildNumericWithSpace(RAT + "", 1));
		// XDR type unsigned int 1 全F
		// 1：合成信令XDR
		// 2：合成业务XDR
		// 3：合成MR XDR
		int XDRtype = 1;
		list.add(Util.buildNumericWithSpace(XDRtype + "", 1));
		// XDR ID byte 16 全F 数据合成服务器生成的唯一XDR编号，与采集解析服务器上报的单接口XDR
		// ID相互独立；一个大流程生成一个XDR ID，关联流程内各接口上的XDR，因此一个合成XDR
		// ID可对应同一UE在不同接口上的多个XDR记录。
		byte[] XDRID = Util.buildStringWithSpace("FFFFFFFFFFFFFFFF", 16);
		list.add(XDRID);
		// IMSI byte 8 全F 用户IMSI（TBCD编码）
		byte[] IMSI = Util.buildStringWithSpace("FFFFFFFF", 8);
		list.add(IMSI);
		// IMEI byte 8 全F 终端IMEI（TBCD编码）
		byte[] IMEI = Util.buildStringWithSpace("FFFFFFFF", 8);
		list.add(IMEI);
		// MSISDN byte 16 全F 用户号码（TBCD编码）
		byte[] MSISDN = Util.buildStringWithSpace("FFFFFFFFFFFFFFFF", 16);
		list.add(MSISDN);
		return Util.bulidByteArr(list);
	}

	/**
	 * @comment 通用信令信息格式
	 * @return
	 * @version: 1.0
	 * @param length
	 * @return
	 */
	public byte[] cc(int length) {
		List<byte[]> list = new ArrayList<byte[]>();
		// Length unsigned int 2 全F 指示整个XDR所占用字节数
		int Length = length + 54;
		list.add(Util.buildNumericWithSpace(Length + "", 2));
		// Procedure Type byte 1 全F 流程类型编码，具体取值如下：
		// 1：Attach
		// 2：Sevice Request
		// 3：Paging
		// 4：TAU
		// 5：Detach
		// 6：PDN connectivity
		// 7：PDN disconnection；
		// 8：EPS bearer resource allocation；
		// 9：EPS bearer resource modify；
		// 10：EPS bearer context deactivation；
		// 11：EPS bearer context modification；
		// 12：Dedicated EPS bearer context activation；
		// 13：X2 handover；
		// 14：S1 handover；
		// 15：UE Context Release；
		// 16：EPS bearer Release
		// 17：CSFB
		// 18：SMS
		// 以上流程的具体说明，如流程开始信令及流程结束信令如何确定，请参考附录A。
		// Procedure Start Time dateTime 8 1970/1/1 0:00
		// 业务流程开始时间，UTC时间，从1970/1/1 00:00:00开始到当前的毫秒数。
		// Procedure End Time dateTime 8 1970/1/1 0:00 业务流程结束时间，UTC时间，从1970/1/1
		// 00:00:00开始到当前的毫秒数。
		// StartLocation-longitude Double 8 全F 取距离procedure start
		// time最近的一个MR对应位置的经度
		// StartLocation-latitude Double 8 全F 取距离procedure start
		// time最近的一个MR对应位置的纬度
		// EndLocation-longitude Double 8 全F 取距离procedure end time最近的一个MR对应位置的经度
		// EndLocation-latitude Double 8 全F 取距离procedure end time最近的一个MR对应位置的纬度
		// Procedure Status byte 1 全F 流程状态
		// 0：成功；
		// 1：失败；
		// 255：超时，或未收到相关的结束流程信令
		// Failure Interface unsigned int 1 全F 如果Procedure Status字段为0，则为全F；
		// 如果Procedure Status字段为1，则指示发生错误的接口类型：
		// 1.Uu
		// 2.X2
		// 3.UE_MR
		// 4.Cell_MR
		// 5.S1-MME
		// 6.S6a
		// 7.S11
		// 8.S10
		// 9.SGs
		// 10.S5/S8
		// 11.S1-U
		// 12.Gn-C
		// 需要说明的是，如果多个接口上发生失败，则此时标识第一个发生失败的接口
		// Failure Cause Unsigned int 2 全F 如果Procedure Status字段为0，则为全F；
		// 如果Procedure Status字段为1，则指示对应Failure
		// interface接口的单接口XDR中的失败原因码。具体的失败原因码定义请参考《中国移动统一DPI设备技术规范-LTE信令采集解析服务器接口规范》
		// Keyword byte 1 全F 用于指示对应不同流程的关键信息，具体定义请参考5.3.2.5节
		// eNB ID byte 4 全F 业务流程发生eNB的eNB ID
		// Cell ID byte 4 全F 流程发生小区的Cell ID，要求为ECI信息
		// MME Group ID byte 2 全F UE当前连接的MME组标识
		// MME Code byte 1 全F UE当前连接的MME编码
		// TAC byte 2 全F UE当前所处的TAC
		// USER_IPv4 byte 4 全F 终端用户的IPv4地址，如无则填全F
		// USER_IPv6 byte 16 全F 终端用户的IPv6地址，如无则填全F
		// New eNB ID byte 4 全F 只针对切换过程，否则填全F
		// New Cell ID byte 4 全F 只针对切换过程，否则填全F
		// New MME Group ID byte 2 全F 只针对切换过程，否则填全F
		// New MME Code byte 1 全F 只针对切换过程，否则填全F
		// New TAC byte 2 全F 只针对TAU过程，否则填全F
		// EPS Bearer Number Unsigned int 1 全F
		// 整数值N，指示后续跟随的承载信息的个数，每个承载信息与一个承载相对应，其中包括多个字段：承载ID，承载类型，QCI，操作结果，用户面传输的GTP-TEID。如果该信令过程不涉及对任何承载的操作，则该字段取值为0，此时该字段之后承载信息的个数为0
		// Bearer 1 ID Unsigned int 1 全F 承载1的EPS bearer ID，取值范围从0到15
		// Bearer 1 Type Unsigned int 1 全F 承载1的类型：
		// 1：default bearer
		// 2：dedicated bearer
		// Bearer 1 QCI Unsigned int 1 全F 承载1的QCI，取值范围从1到9
		// Bearer 1 Status Unsigned int 1 全F 承载1的操作结果：
		// 1：建立成功
		// 2：建立失败
		// 3：修改成功
		// 4：修改失败
		// 5：释放成功
		// 6：释放失败
		// Bearer 1 eNB GTP-TEID byte 4 全F 承载1对应的eNB侧GTP-TEID。
		// Bearer 1 SGW GTP-TEID byte 4 全F 承载1对应的SGW侧GTP-TEID。
		// ……
		// Bearer N ID Unsigned int 1 全F 承载N的EPS bearer ID，取值范围从0到15
		// Bearer N Type Unsigned int 1 全F 承载N的类型：
		// 1：default bearer
		// 2：dedicated bearer
		// Bearer N QCI Unsigned int 1 全F 承载N的QCI，取值范围从1到9
		// Bearer N Status Unsigned int 1 全F 承载N的操作结果：
		// 1：建立成功
		// 2：建立失败
		// 3：修改成功
		// 4：修改失败
		// 5：释放成功
		// 6：释放失败
		// Bearer N eNB GTP-TEID byte 4 全F 承载N对应的eNB侧GTP-TEID
		// Bearer N SGW GTP-TEID byte 4 全F 承载N对应的SGW侧GTP-TEID
		// XDRnumber Unsigned int 1 0 该合成信令XDR中包含的单接口信令信息个数
		return Util.bulidByteArr(list);
	}

	/**
	 * @comment 单接口信令信息格式
	 * @return
	 * @version: 1.0
	 * @param length
	 * @return
	 */
	public byte[] dd(int length) {
		List<byte[]> list = new ArrayList<byte[]>();
		// Length unsigned int 2 全F 指示整个XDR所占用字节数
		int Length = length + 54;
		list.add(Util.buildNumericWithSpace(Length + "", 2));
		// Interface unsigned int 1 全F 接口类型：
		// 1.Uu
		// 2.X2
		// 5.S1-MME
		// 6.S6a
		// 7.S11
		// 8.S10
		// 9.SGs
		// 10.S5/S8
		// 11.S1-U
		// 12.Gn-C
		// XDR ID byte 16 全F 采集解析服务器上报的各接口内部的XDR编号；
		// Procedure Type byte 1 全F 各接口流程类型，重用各接口XDR中的“Procedure Type”字段
		// Procedure Start Time dateTime 8 1970/1/1 0:00
		// 业务流程开始时间，UTC时间，从1970/1/1 00:00:00开始到当前的毫秒数。
		// Procedure End Time dateTime 8 1970/1/1 0:00 业务流程结束时间，UTC时间，从1970/1/1
		// 00:00:00开始到当前的毫秒数。
		// StartLocation-longitude Double 8 全F 取距离procedure start
		// time最近的一个MR对应位置的经度，只针对Uu及S1-MME接口，对于其他接口填全F
		// StartLocation-latitude Double 8 全F 取距离procedure start
		// time最近的一个MR对应位置的纬度，只针对Uu及S1-MME接口，对于其他接口填全F
		// EndLocation-longitude Double 8 全F 取距离procedure end
		// time最近的一个MR对应位置的经度，只针对Uu及S1-MME接口，对于其他接口填全F
		// EndLocation-latitude Double 8 全F 取距离procedure end
		// time最近的一个MR对应位置的纬度，只针对Uu及S1-MME接口，对于其他接口填全F
		// Procedure Status int 1 全F 流程状态
		// 0：成功；
		// 1：失败；
		// 255：超时，或未收到相关的结束流程信令
		// Cause byte 1 全F 重用各接口XDR中的“Failure Cause”或“Cause”字段
		return Util.bulidByteArr(list);
	}
	
	/**
	 * @comment 通用业务信息格式
	 * @return
	 * @version: 1.0
	 * @param length
	 * @return
	 */
	public byte[] ee(int length) {
		List<byte[]> list = new ArrayList<byte[]>();
		// Length unsigned int 2 全F 指示整个XDR所占用字节数
		int Length = length + 54;
		list.add(Util.buildNumericWithSpace(Length + "", 2));
//		App Type	unsigned byte	2	全F	应用大类
//		业务类型，集团规定的18种大类
//		App Sub-type	unsigned byte	2	全F	应用小类
//		根据集团定义的识别规则识别出来的小类,例如新浪微博和腾讯微博如果属于不同的应用，则有不同的ID。
//		集团未定义的各厂家根据自己的DPI进行识别
//		Procedure Start Time	dateTime	8	1970/1/1 0:00	TCP/UDP流开始时间，UTC时间，从1970/1/1 00:00:00开始到当前的毫秒数。
//		Procedure End Time	dateTime	8	1970/1/1 0:00	TCP/UDP流结束时间，UTC时间，从1970/1/1 00:00:00开始到当前的毫秒数。
//		StartLocation-longitude	Double 	8	全F	取距离procedure start time最近的一个MR对应位置的经度
//		StartLocation-latitude	Double 	8	全F	取距离procedure start time最近的一个MR对应位置的纬度
//		EndLocation-longitude	Double 	8	全F	取距离procedure end time最近的一个MR对应位置的经度
//		EndLocation-latitude	Double 	8	全F	取距离procedure end time最近的一个MR对应位置的纬度
//		USER_IPv4	byte	4	全F	终端用户的IPv4地址，如无则填全F
//		USER_IPv6	byte	16	全F	终端用户的IPv6地址，如无则填全F
//		XDRnumber	unsigned int	1	0	该合成业务XDR中包含的单小区业务信息个数
		return Util.bulidByteArr(list);
	}
	
	/**
	 * @comment 单小区业务信息格式
	 * @return
	 * @version: 1.0
	 * @param length
	 * @return
	 */
	public byte[] ff(int length) {
		List<byte[]> list = new ArrayList<byte[]>();
		// Length unsigned int 2 全F 指示整个XDR所占用字节数
		int Length = length + 54;
		list.add(Util.buildNumericWithSpace(Length + "", 2));
//		XDR ID	unsigned byte	16	全F	采集解析服务器上报的S1-U接口XDR的XDR ID。
//		Procedure Start Time	dateTime	8	1970/1/1 0:00	TCP/UDP流开始时间，UTC时间），从1970/1/1 00:00:00开始到当前的毫秒数。
//		Procedure End Time	dateTime	8	1970/1/1 0:00	TCP/UDP流结束时间，UTC时间），从1970/1/1 00:00:00开始到当前的毫秒数。
//		StartLocation-longitude	Double 	8	全F	取距离procedure start time最近的一个MR对应位置的经度
//		StartLocation-latitude	Double 	8	全F	取距离procedure start time最近的一个MR对应位置的纬度
//		EndLocation-longitude	Double 	8	全F	取距离procedure end time最近的一个MR对应位置的经度
//		EndLocation-latitude	Double 	8	全F	取距离procedure end time最近的一个MR对应位置的纬度
//		eNB ID	byte	2	全F	eNB ID
//		Cell ID	byte	4	全F	小区的ECI
//		eNB GTP-TEID	byte	4	全F	eNB侧用户面GTP-TEID
//		SGW GTP-TEID	byte	4	全F	SGW侧用户面GTP-TEID
//		UL Data	byte	4	全F	上行流量
//		按照3GPP SGSN话单的统计方式进行计算，单位：字节
//		DL Data	byte	4	全F	下行流量
//		按照3GPP SGSN话单的统计方式进行计算，单位：字节
		return Util.bulidByteArr(list);
	}
	
	/**
	 * @comment MR信息格式
	 * @return
	 * @version: 1.0
	 * @param length
	 * @return
	 */
	public byte[] gg(int length) {
		List<byte[]> list = new ArrayList<byte[]>();
		// Length unsigned int 2 全F 指示整个XDR所占用字节数
		int Length = length + 54;
		list.add(Util.buildNumericWithSpace(Length + "", 2));
//		Location-longitude	Double 	8	全F	该MR对应位置的经度信息
//		Location-latitude	Double 	8	全F	该MR对应位置的纬度信息
//		eNB ID	byte	4	全F	流程发生的eNB ID，软采包头上报
//		Cell ID	byte	4	全F	流程发生小区的Cell ID，要求为ECI信息，软采包头上报
//		Time	dateTime	8	1970/1/1 0:00	该MR对应的时间戳，UTC时间，从1970/1/1 00:00:00开始到当前的毫秒数。
//		MR type	Unsigned int	1	全F	本条测量报告的类型，由采集解析设备通过解析measurement configuration和 MR的meas ID后获得：
//		1：周期测量
//		2：A1事件
//		3：A2事件
//		4：A3事件
//		5：A4事件
//		6：A5事件
//		7：B1事件
//		8：B2事件
//		9：其他
//		PHR	Unsigned int	1	全F	UE相对于配置的最大发射功率的余量。在headroom type 1中，此余量表示服务小区的UL-SCH发射功率与配置的最大发射功率的差值。在headroom type 2中，此余量表示每个激活的服务小区UL-SCH发射功率或者是PCell的PUSCH和PUCCH发射功率值和与配置的最大发射功率的差值。
//		若MR type为事件性测量报告，该字段取全F。
//		eNB Received Power	Unsigned int	2	全F	eNB接收UE的总功率
//		UE的PUSCH占用的所有PRB的总功率；
//		若MR type为事件性测量报告，该字段取全F。
//		UL SINR	Unsigned int	1	全F	用户上行信噪比
//		具体计算方法：计算用户占用的每个物理资源块（PRB）带宽上的信号功率S和干扰功率I的比值，然后取所有PRB信噪比的平均值。
//		若MR type为事件性测量报告，该字段取全F。
//		Serving Freq	Unsigned int	2	全F	服务小区的EARFCN
//		Serving RSRP	Unsigned int	1	全F	服务小区RSRP
//		Serving RSRQ	Unsigned int	1	全F	服务小区RSRQ
//		Neighbor Cell Number	Unsigned int	1	全F	整数值N，指示后续跟随的邻区信息的个数，每个邻区信息与一个邻小区相对应，其中包括三个字段：Cell ID、RSRP、RSRQ。
//		Neighbor 1 Cell ID	Unsigned int	1	全F	第一个邻小区的PCI
//		Neighbor 1 Freq	Unsigned int	2	全F	第一个邻小区的EARFCN
//		Neighbor 1 RSRP	Unsigned int	1	全F	第一个邻小区的RSRP测量值
//		Neighbor 1 RSRQ	Unsigned int	1	全F	第一个邻小区的RSRQ测量值
//		……				
//		Neighbor N Cell ID	Unsigned int	1	全F	第N个邻小区的PCI
//		Neighbor N Freq	Unsigned int	2	全F	第N个邻小区的EARFCN
//		Neighbor N RSRP	Unsigned int	1	全F	第N个邻小区的RSRP测量值
//		Neighbor N RSRQ	Unsigned int	1	全F	第N个邻小区的RSRQ测量值
		return Util.bulidByteArr(list);
	}
}